﻿//========================================================= 
/**@file CommonCmdDriver.h
 * @brief 一些基本的公共命令
 * 
 * @date 2016-05-11   21:10:19
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_COMMONCMDDRIVER_H_
#define _LIBZHOUYB_COMMONCMDDRIVER_H_
//--------------------------------------------------------- 
#include "CommandDriver.h"
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace driver {
//--------------------------------------------------------- 
/**
 * @brief 枚举所有支持的命令
 * @date 2016-05-07 11:11
 *
 * @param Name : string [default:""] 需要枚举的命令名称(部分匹配)
 *
 * @retval CMD : string 获取到的命令
 * @retval Count : uint 获取到的命令数目
 */
#define LC_CMD_ENUMCOMMAND() \
    LC_CMD_METHOD(EnumCommand) \
    { \
        list_t<Ref<ComplexCommand> > cmdlist; \
        list_t<Ref<ComplexCommand> >::iterator itr; \
        string name = arg["Name"].To<string>(); \
        ByteArray n(name.c_str(), name.length()); \
        this->GetCommand(n, cmdlist); \
        for(itr = cmdlist.begin();itr != cmdlist.end(); ++itr) \
        { \
            rlt.Put("CMD", (*itr)->Name()); \
        } \
        rlt.Put("Count", ArgConvert::ToString(cmdlist.size())); \
        return true; \
    }
/// 注册LC_CMD_ENUMCOMMAND
#define _RegisteEnumCMD(cls) _RegisteCMD(cls, EnumCommand)
/// 剔除LC_CMD_ENUMCOMMAND
#define _RemoveEnumCMD(cmds) \
    do { \
        _RemoveCMD(cmds, EnumCommand); \
    } while(false)
//--------------------------------------------------------- 
/// 类中导出支持的接口
#define LC_CMD_INTERFACE(iinterface, refInterface) \
    LC_CMD_METHOD(Ref_##iinterface) \
    { \
        pointer p = reinterpret_cast<pointer>(&(refInterface)); \
        rlt.Put(#iinterface, ArgConvert::ToString(p)); \
        return true; \
    }
/// 类中导出属性
#define LC_INTERFACE_GETTER(iinterface, refInterface) \
    const Ref<iinterface> Get##iinterface() const { return refInterface; }
/// 类中导出命令和接口
#define LC_CMD_INTERFACE_GETTER(iinterface, refInterface) \
    LC_CMD_INTERFACE(iinterface, refInterface) \
    LC_INTERFACE_GETTER(iinterface, refInterface)
/// 在类中调用指定接口的命令
#define LC_CALL_INTERFACE(iinterface) Ref_##iinterface(arg, rlt)
/// 类中注册自己的接口函数
#define _RegisteInterfaceCMD(cls, iinterface) (this->_Registe(#iinterface, Command::Make(*this, &cls::Ref_##iinterface, #cls"::"#iinterface)))
/// 移除命令组中的某个命令
#define _RemoveCMD(cmds, name) CommandCollection::RemoveCommand(cmds, #name)
//--------------------------------------------------------- 
#define LC_LASTERR_INVOKE(refLastErr) \
    virtual int GetLastErr() const \
    { \
        Ref<ILastErrBehavior> ref = (refLastErr); \
        if(ref.IsNull()) \
            return DeviceError::Success; \
        return ref->GetLastErr(); \
    } \
    virtual const char* GetErrMessage() \
    { \
        Ref<ILastErrBehavior> ref = (refLastErr); \
        if(ref.IsNull()) \
            return ""; \
        return ref->GetErrMessage(); \
    } \
    virtual void ResetErr() \
    { \
        Ref<ILastErrBehavior> ref = (refLastErr); \
        if(!ref.IsNull()) \
        { \
            ref->ResetErr(); \
        } \
    }

/*
 * @brief 获取上次失败的错误码和错误信息
 * @date 2016-06-25 17:38
 *
 * @parem [in] IsReset : bool [default:true] 是否自动清除错误状态
 *
 * @retval CODE : int 上次的错误码
 * @retval MSG : string 上次的错误信息
 * @return true:有错误信息;false:没有错误信息
 */
// LC_CMD_METHOD(LastError);

/// 获取上次错误信息的接口命令
#define LC_CMD_LASTERR(refLastErrBehavior) \
    LC_CMD_METHOD(LastError) \
    { \
        Ref<ILastErrBehavior> ref = (refLastErrBehavior); \
        if(ref.IsNull()) \
            return false; \
        int errCode = ref->GetLastErr(); \
        rlt.Put("CODE", ArgConvert::ToString<int>(errCode)); \
        if(!DeviceError::IsSuccess(errCode)) \
        { \
            rlt.Put("MSG", ref->GetErrMessage()); \
        } \
        bool isReset = arg["IsReset"].To<bool>(true); \
        if(isReset) \
        { \
            ref->ResetErr(); \
        } \
        return true; \
    } \
    LC_CMD_METHOD(ResetError) \
    { \
        Ref<ILastErrBehavior> ref = (refLastErrBehavior); \
        if(ref.IsNull()) \
            return false; \
        ref->ResetErr(); \
        return true; \
    }

#define LC_CMD_LASTERR_INVOKE(lastErrInvoker) \
    LC_LASTERR_INVOKE(lastErrInvoker) \
    LC_CMD_LASTERR(lastErrInvoker)

#define _RegisteLastErrCMD(cls) \
    do { \
        _RegisteCMD(cls, LastError); \
        _RegisteCMD(cls, ResetError); \
    } while(false)

#define _RemoveLastErrCMD(cmds) \
    do { \
        _RemoveCMD(cmds, LastError); \
        _RemoveCMD(cmds, ResetError); \
    } while(false)
//--------------------------------------------------------- 
#define LC_CMD_INTERRUPT_INVOKE(refInterruptInvoker) \
    Ref<IInterrupter> SetInterrupter(const Ref<IInterrupter>& interrupter) \
    { \
        Ref<IInterrupter> ref = (refInterruptInvoker); \
        if(ref.IsNull()) \
            return Ref<IInterrupter>(); \
        return ref->SetInterrupter(interrupter); \
    } \
    LC_CMD_METHOD(SetInterrupter) \
    { \
        Ref<IInterrupter> ref = CommandDriverHelper::CommandRef<IInterrupter>(arg, "IInterrupter"); \
        SetInterrupter(ref); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "IInterrupter is null"); \
        } \
        return !(ref.IsNull()); \
    }

#define LC_CMD_INTERRUPT(refInterruptBehavior) \
    Ref<IInterrupter> SetInterrupter(const Ref<IInterrupter>& interrupter) \
    { \
        Ref<InterruptBehavior> ref = (refInterruptBehavior); \
        if(ref.IsNull()) \
            return Ref<IInterrupter>(); \
        Ref<IInterrupter> lastInterrupter = ref->Interrupter; \
        ref->Interrupter = interrupter; \
        return lastInterrupter; \
    } \
    LC_CMD_METHOD(SetInterrupter) \
    { \
        Ref<InterruptBehavior> refBehavior = (refInterruptBehavior); \
        if(refBehavior.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InterruptBehavior is null"); \
            return false; \
        } \
        Ref<IInterrupter> ref = CommandReflectArg(IInterrupter, arg); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "IInterrupter is null"); \
        } \
        refBehavior->Interrupter = ref; \
        return !(ref.IsNull()); \
    }

#define _RegisteIInterruptCMD(cls) _RegisteCMD(cls, SetInterrupter)

#define _RemoveIInterruptCMD(cmds) _RemoveCMD(cmds, SetInterrupter)

/// 等待取消的默认最大超时时间
#ifndef DEV_CANCEL_TIMEOUT
#   define DEV_CANCEL_TIMEOUT 500
#endif

/*
 * @brief 中断当前操作,中断后需手动重置状态(仅在非阻塞线程内有效)
 * @date 2016-06-25 17:38
 *
 * @retval Timeout : uint 中断尝试的最大超时时间
 */
// LC_CMD_METHOD(Interrupt)

/*
 * @brief 取消当前操作,中断后不需要手动重置状态(仅在非阻塞线程内有效)
 * @date 2016-06-25 17:38
 *
 * @retval Timeout : uint 中断尝试的最大超时时间
 */
// LC_CMD_METHOD(Cancel);

/*
 * @brief 重置中断状态
 * @date 2016-06-25 17:38
 */
// LC_CMD_METHOD(InterruptReset);

/// 中断器操作的接口命令
#define LC_CMD_INTERRUPT_OPERATION(refInterrupterBehavior) \
    LC_CMD_METHOD(Interrupt) \
    { \
        Ref<InterruptBehavior> ref = (refInterrupterBehavior); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InterrupterBehavior is null"); \
            return false; \
        } \
        uint timeoutMs = arg["Timeout"].To<uint>(0); \
        return InterruptBehavior::Interrupt(ref, timeoutMs); \
    } \
    LC_CMD_METHOD(Cancel) \
    { \
        Ref<InterruptBehavior> ref = (refInterrupterBehavior); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InterrupterBehavior is null"); \
            return false; \
        } \
        uint timeoutMs = arg["Timeout"].To<uint>(DEV_CANCEL_TIMEOUT); \
        return InterruptBehavior::Cancel(ref, timeoutMs); \
    } \
    LC_CMD_METHOD(InterruptReset) \
    { \
        Ref<InterruptBehavior> ref = (refInterrupterBehavior); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InterrupterBehavior is null"); \
            return false; \
        } \
        InterruptBehavior::Reset(ref); \
        return true; \
    }

#define _RegisteIInterruptOperationCMD(cls) \
    do { \
        _RegisteCMD(cls, Interrupt); \
        _RegisteCMD(cls, Cancel); \
        _RegisteCMD(cls, InterruptReset); \
    } while(false)

#define _RemoveIInterruptOperationCMD(cmds) \
    do { \
        _RemoveCMD(cmds, Interrupt); \
        _RemoveCMD(cmds, Cancel); \
        _RemoveCMD(cmds, InterruptReset); \
    } while(false)
//---------------------------------------------------------
/// 支持取消功能的接口
#define LC_CMD_CANCEL(refInterrupterBehavior) \
    LC_CMD_INTERRUPT(refInterrupterBehavior); \
    LC_CMD_INTERRUPT_OPERATION(refInterrupterBehavior)

#define _RegisteCancelCMD(cls) \
    _RegisteIInterruptCMD(cls); \
    _RegisteIInterruptOperationCMD(cls)

#define _RemoveCancelCMD(cls) \
    _RemoveIInterruptCMD(cls); \
    _RemoveIInterruptOperationCMD(cls)
//--------------------------------------------------------- 
#define LC_ADAPTER_INVOKE(deviceType, refAdapterInvoker) \
    virtual void SelectDevice(const Ref<deviceType>& dev) \
    { \
        Ref<IBaseDevAdapterBehavior<deviceType> > ref = (refAdapterInvoker); \
        if(ref.IsNull()) \
            return ; \
        BaseDevAdapterBehavior::SelectDevice(dev); \
        ref->SelectDevice(dev); \
    } \
    virtual void ReleaseDevice() \
    { \
        Ref<IBaseDevAdapterBehavior<deviceType> > ref = (refAdapterInvoker); \
        if(ref.IsNull()) \
            return ; \
        BaseDevAdapterBehavior::ReleaseDevice(); \
        ref->ReleaseDevice(); \
    } \
    virtual Ref<deviceType>& ActiveDevice() \
    { \
        return BaseDevAdapterBehavior::ActiveDevice(); \
    }
/// 导出适配器接口命令
#define LC_CMD_ADAPTER_DEFINE(deviceType, select, release, refObj) \
    LC_CMD_METHOD(SelectDevice) \
    { \
        Ref<deviceType> ref = CommandReflectArg(deviceType, arg); \
        if(ref.IsNull()) \
        { \
            rlt.Put("Adapter", #deviceType); \
            this->_logErr(DeviceError::ArgIsNullErr, #deviceType" is null"); \
            return false; \
        } \
        select; \
        return true; \
    } \
    LC_CMD_METHOD(ReleaseDevice) \
    { \
        release; \
        return true; \
    } \
    LC_CMD_METHOD(ActiveDevice) \
    { \
        if((refObj).IsNull()) \
        { \
            this->_logErr(DeviceError::DevInvalidErr); \
            return false; \
        } \
        pointer p = reinterpret_cast<pointer>(&(refObj)); \
        rlt.Put(#deviceType, ArgConvert::ToString(p)); \
        return true; \
    }
/// 适配器接口命令
#define LC_CMD_ADAPTER_THIS(deviceType) LC_CMD_ADAPTER_DEFINE(deviceType, \
    BaseDevAdapterBehavior::SelectDevice(ref), \
    BaseDevAdapterBehavior::ReleaseDevice(), \
    BaseDevAdapterBehavior::ActiveDevice())
/// 适配器接口命令
#define LC_CMD_ADAPTER(deviceType, obj) LC_CMD_ADAPTER_DEFINE(deviceType, \
    obj.SelectDevice(ref), \
    obj.ReleaseDevice(), \
    obj.ActiveDevice())

#define LC_CMD_ADAPTER_INVOKE(deviceType, adapterInvoker) \
    LC_ADAPTER_INVOKE(deviceType, adapterInvoker) \
    LC_CMD_ADAPTER(deviceType, (*this))

#define _RegisteAdapterCMD(cls) \
    do { \
        _RegisteCMD(cls, SelectDevice); \
        _RegisteCMD(cls, ReleaseDevice); \
        _RegisteCMD(cls, ActiveDevice); \
    } while(false)

#define _RemoveAdapterCMD(cmds) \
    do { \
        _RemoveCMD(cmds, SelectDevice); \
        _RemoveCMD(cmds, ReleaseDevice); \
        _RemoveCMD(cmds, ActiveDevice); \
    } while(false)
//--------------------------------------------------------- 
/*
 * @brief 设置设备读写超时时间
 * @date 2016-06-25 17:38
 *
 * @param [in] Timeout : uint 超时时间(ms)
 * @param [in] Interval : uint 等待间隔(ms)
 *
 * @retval Timeout : uint 上次的超时时间(ms)
 * @retval Interval : uint 上次的等待间隔(ms)
 */
// LC_CMD_METHOD(SetTimeoutMS);

/// 超时时间行为接口命令
#define LC_CMD_TIMEOUT(refTimeoutBehavior) \
    LC_CMD_METHOD(SetTimeoutMS) \
    { \
        Ref<ITimeoutBehavior> ref = (refTimeoutBehavior); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "TimeoutBehavior is null"); \
            return false; \
        } \
        const char TimeoutMS[] = "Timeout"; \
        const char IntervalMS[] = "Interval"; \
        uint timeoutMs = 0; \
        if(arg[TimeoutMS].Get<uint>(timeoutMs)) \
        { \
            uint lastTimeoutMs = ref->SetWaitTimeout(timeoutMs); \
            rlt.Put(TimeoutMS, ArgConvert::ToString<uint>(lastTimeoutMs)); \
        } \
        uint intervalMs = 0; \
        if(arg[IntervalMS].Get<uint>(intervalMs)) \
        { \
            uint lastIntervalMs = ref->SetOperatorInterval(intervalMs); \
            rlt.Put(IntervalMS, ArgConvert::ToString<uint>(lastIntervalMs)); \
        } \
        return true; \
    }

#define _RegisteITimeoutCMD(cls) _RegisteCMD(cls, SetTimeoutMS)

#define _RemoveITimeoutCMD(cmds) _RemoveCMD(cmds, SetTimeoutMS)
//--------------------------------------------------------- 
/// 类中导出ILoggerBehavior接口
#ifdef OPEN_LOGGER
#   define LC_LOGGER_INVOKE(loggerInvoker) \
    virtual void SelectLogger(const LoggerAdapter& log) \
    { \
        LoggerBehavior::SelectLogger(log); \
        loggerInvoker.SelectLogger(log); \
    } \
    virtual void ReleaseLogger(const LoggerAdapter* plog = NULL) \
    { \
        LoggerBehavior::ReleaseLogger(plog); \
        loggerInvoker.ReleaseLogger(plog); \
    }

#   define LC_CMD_LOGGER(refLoggerBehavior) \
    LC_CMD_METHOD(SelectLogger) \
    { \
        Ref<ILoggerBehavior> refBehavior = (refLoggerBehavior); \
        if(refBehavior.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "LoggerBehavior is null"); \
            return false; \
        } \
        Ref<LoggerAdapter> ref = CommandReflectArg(LoggerAdapter, arg); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "ILogger is null"); \
            return false; \
        } \
        this->_log.Select(ref); \
        refBehavior->SelectLogger(ref); \
        return true; \
    } \
    LC_CMD_METHOD(ReleaseLogger) \
    { \
        Ref<ILoggerBehavior> refBehavior = (refLoggerBehavior); \
        if(refBehavior.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "LoggerBehavior is null"); \
            return false; \
        } \
        this->_log.Release(); \
        refBehavior->ReleaseLogger(); \
        return true; \
    }

#   define LC_CMD_LOGGER_INVOKE(loggerInvoker) \
    LC_LOGGER_INVOKE(loggerInvoker) \
    LC_CMD_LOGGER(*this)

#   define _RegisteLoggerCMD(cls) \
    do { \
        _RegisteCMD(cls, SelectLogger); \
        _RegisteCMD(cls, ReleaseLogger); \
    } while(false)

#   define _RemoveLoggerCMD(cmds) \
    do { \
        _RemoveCMD(cmds, SelectLogger); \
        _RemoveCMD(cmds, ReleaseLogger); \
    } while(false)

#else
#   define LC_LOGGER_INVOKE(loggerInvoker)
#   define LC_CMD_LOGGER(loggerBehavior) 
#   define LC_CMD_LOGGER_INVOKE(loggerInvoker)
#   define _RegisteLoggerCMD(cls) 
#   define _RemoveLoggerCMD(cmds)
#endif
//--------------------------------------------------------- 
/*
 * @brief 打开设备
 * @date 2016-06-25 17:38
 *
 * @param [in] Arg : string 打开设备的参数
 */
// LC_CMD_METHOD(Open);

// 返回设备是否已经打开
// LC_CMD_METHOD(IsOpen);

// 关闭设备
// LC_CMD_METHOD(Close);

/// 设备基本操作接口命令
#define LC_CMD_BASEDEVICE(refBaseDevice) \
    LC_CMD_METHOD(Open) \
    { \
        Ref<IBaseDevice> ref = (refBaseDevice); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "BaseDevice is null"); \
            return false; \
        } \
        string sArg = arg["Arg"].To<string>(); \
        if(!(ref->Open(sArg.c_str()))) \
        { \
            _logErr(DeviceError::DevOpenErr); \
            return false; \
        } \
        return true; \
    } \
    LC_CMD_METHOD(IsOpen) \
    { \
        Ref<IBaseDevice> ref = (refBaseDevice); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "BaseDevice is null"); \
            return false; \
        } \
        return ref->IsOpen(); \
    } \
    LC_CMD_METHOD(Close) \
    { \
        Ref<IBaseDevice> ref = (refBaseDevice); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "BaseDevice is null"); \
            return false; \
        } \
        ref->Close(); \
        return true; \
    }

/// 注册设备基础接口
#define _RegisteIBaseDeviceCMD(cls) \
    do { \
        _RegisteCMD(cls, Open); \
        _RegisteCMD(cls, IsOpen); \
        _RegisteCMD(cls, Close); \
    } while(false)

#define _RemoveIBaseDeviceCMD(cmds) \
    do { \
        _RemoveCMD(cmds, Open); \
        _RemoveCMD(cmds, IsOpen); \
        _RemoveCMD(cmds, Close); \
    } while(false)
//--------------------------------------------------------- 
/*
 * @brief 发送数据
 * @date 2016-06-25 17:38
 *
 * @param [in] Send : hex 需要发送的指令数据(DevCommand::Format格式)
 */
// LC_CMD_METHOD(Write);

/*
 * @brief 接收数据
 * @date 2016-06-25 17:38
 *
 * @retval Recv : hex 接收到的指令数据
 */
// LC_CMD_METHOD(Read);

/// 收发数据的接口命令
#define LC_CMD_INTERACTIVETRANS(refInteractiveTrans) \
    LC_CMD_METHOD(Write) \
    { \
        Ref<IInteractiveTrans> ref = (refInteractiveTrans); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InteractiveTrans is null"); \
            return false; \
        } \
        string sCmd; \
        if(!arg["Send"].Get<string>(sCmd)) \
            return true; \
        if(!(ref->Write(DevCommand::FromAscii(sCmd.c_str())))) \
        { \
            _logErr(DeviceError::SendErr); \
            return false; \
        } \
        return true; \
    } \
    LC_CMD_METHOD(Read) \
    { \
        Ref<IInteractiveTrans> ref = (refInteractiveTrans); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "InteractiveTrans is null"); \
            return false; \
        } \
        ByteBuilder rCmd(8); \
        if(!(ref->Read(rCmd))) \
        { \
            _logErr(DeviceError::RecvErr); \
            return false; \
        } \
        rlt.Put("Recv", ArgConvert::ToString(rCmd)); \
        return true; \
    }
#define _RegisteIInteractiveTransCMD(cls) \
    do { \
        _RegisteCMD(cls, Write); \
        _RegisteCMD(cls, Read); \
    } while(false)
#define _RemoveIInteractiveTransCMD(cmds) \
    do { \
        _RemoveCMD(cmds, Write); \
        _RemoveCMD(cmds, Read); \
    } while(false)
//--------------------------------------------------------- 
/*
 * @brief 交互指令
 * 
 * @param [in] sApdu : hex 需要发送的指令
 * 
 * @retval rApdu : hex 接收到的APDU
 */
// LC_CMD_METHOD(Apdu)

/*
 * @brief 交互多条APDU
 * 
 * @param [in] sApdu : hex 需要发送的指令串
 * 
 * @retval rApdu : hex 接收到的APDU
 */
// LC_CMD_METHOD(ApduArray)

/// IC卡指令交互接口
#define LC_CMD_ICCARDTRANSMIT(refIC) \
    LC_CMD_METHOD(Apdu) \
    { \
        Ref<IICCardDevice> ref = (refIC); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "ICCardDevice is null"); \
            return false; \
        } \
        ByteBuilder sCmd(32); \
        ByteBuilder rCmd(32); \
        string sApdu = arg["sApdu"].To<string>(); \
        ByteConvert::FromAscii(sApdu.c_str(), sCmd); \
        if(!(ref->Apdu(sCmd, rCmd))) \
        { \
            _logErr(DeviceError::TransceiveErr); \
            return false; \
        } \
        ByteBuilder tmp(8); \
        ByteConvert::ToAscii(rCmd, tmp); \
        rlt.Put("rApdu", tmp.GetString()); \
        return true; \
    } \
    LC_CMD_METHOD(ApduArray) \
    { \
        Ref<IICCardDevice> ref = (refIC); \
        if(ref.IsNull()) \
        { \
            this->_logErr(DeviceError::ArgIsNullErr, "ICCardDevice is null"); \
            return false; \
        } \
        ByteBuilder sCmd(32); \
        ByteBuilder rCmd(32); \
        bool bApdu = true; \
        list_t<string> apduList; \
        arg.Get("sApdu", apduList); \
        for(list_t<string>::iterator itr = apduList.begin();itr != apduList.end(); ++itr) \
        { \
            if(bApdu) \
            { \
                sCmd.Clear(); \
                ByteConvert::FromAscii(itr->c_str(), sCmd); \
                rCmd.Clear(); \
                bApdu = ref->Apdu(sCmd, rCmd); \
                sCmd.Clear(); \
                ByteConvert::ToAscii(rCmd, sCmd); \
                rlt.Put("rApdu", sCmd.GetString()); \
            } \
            if(!bApdu) \
            { \
                _logErr(DeviceError::TransceiveErr, (*itr).c_str()); \
            } \
        } \
        return bApdu; \
    }

/// 注册IC卡交互命令
#define _RegisteIICCardTransmitCMD(cls) \
    do { \
        _RegisteCMD(cls, Apdu); \
        _RegisteCMD(cls, ApduArray); \
    } while(false)

#define _RemoveIICCardTransmitCMD(cmds) \
    do { \
        _RemoveCMD(cmds, Apdu); \
        _RemoveCMD(cmds, ApduArray); \
    } while(false)

/// 注册IC卡所有接口命令
#define _RegisteIICCardCMD(cls) \
    do { \
        _RegisteCMD(cls, PowerOn); \
        _RegisteCMD(cls, IsActive); \
        _RegisteCMD(cls, Apdu); \
        _RegisteCMD(cls, ApduArray); \
        _RegisteCMD(cls, PowerOff); \
    } while(false)
    
#define _RemoveIICCardCMD(cmds) \
    do { \
        _RemoveCMD(cmds, PowerOn); \
        _RemoveCMD(cmds, IsActive); \
        _RemoveCMD(cmds, Apdu); \
        _RemoveCMD(cmds, ApduArray); \
        _RemoveCMD(cmds, PowerOff); \
    } while(false)
//--------------------------------------------------------- 
/// 剔除不需要再配置的命令
#define LC_CMD_EXCEPT() LC_CMD_METHOD(ExceptCommand)
/// 注册ExceptCommand
#define _RegisteExceptCMD(cls) _RegisteCMD(cls, ExceptCommand)
/// 剔除ExceptCommand
#define _RemoveExceptCMD(cmds) \
    do { \
        _RemoveCMD(cmds, ExceptCommand); \
    } while(false)
/// 在ExceptCommand中剔除不需要外部配置的命令
#define EXCEPT_CMD(cmdName) rlt.Put("Cmd", #cmdName)
//--------------------------------------------------------- 
/**
 * @brief 编译版本
 * @date 2017-02-11 16:06
 * 
 * @retval Version : string 编译时的版本信息
 */
#define LC_CMD_VERSION() \
    LC_CMD_METHOD(CompileVersion) \
    { \
        string sVersion = __DATE__; \
        sVersion += " "; \
        sVersion += __TIME__; \
        rlt.Put("Version", sVersion); \
        return true; \
    }
/// 注册LC_CMD_VERSION
#define _RegisteVersionCMD(cls) _RegisteCMD(cls, CompileVersion)
/// 剔除LC_CMD_VERSION
#define _RemoveVersionCMD(cmds) \
    do { \
        _RemoveCMD(cmds, CompileVersion); \
    } while(false)
//--------------------------------------------------------- 
/// 托管两个变量实现ILastErrBehavior
class LastErrInvoker : public ILastErrBehavior, public RefObject
{
protected:
    int* _pErr;
    string* _pMsg;
public:
    LastErrInvoker()
    {
        _pErr = NULL;
        _pMsg = NULL;
    }
    /// 设置托管的数据(由于LastErrBehavior类的err和msg为私有成员,所以只能通过变量的方式实现)
    inline LastErrInvoker& Invoke(int& err, string& msg)
    {
        _pErr = &err;
        _pMsg = &msg;
        return (*this);
    }
    inline bool IsValid() const
    {
        return _pErr != NULL && _pMsg != NULL;
    }
    inline LastErrInvoker& Uninvoke()
    {
        _pErr = NULL;
        _pMsg = NULL;
        return (*this);
    }
    virtual int GetLastErr() const
    {
        if(_pErr != NULL)
            return (*_pErr);
        return DeviceError::Success;
    }
    /// 获取错误的描述信息(string字符串描述)
    virtual const char* GetErrMessage()
    {
        if(_pMsg != NULL)
            return _pMsg->c_str();
        return "";
    }
    /// 重置错误信息
    virtual void ResetErr()
    {
        (*_pErr) = DeviceError::Success;
        (*_pMsg) = "";
    }
};
//--------------------------------------------------------- 
/// 统一设置多个InterruptBehavior
class InterruptSetter : 
    public selecter<Ref<InterruptBehavior> >, 
    public InterruptBehavior,
    public RefObject
{
public:
    /// 选择类型定义
    typedef selecter<Ref<InterruptBehavior> > SelecterType;
    /// 设置中断器并返回设置前的中断器
    virtual Ref<IInterrupter> SetInterrupter(const Ref<IInterrupter>& interrupter)
    {
        Ref<IInterrupter> lastInterrupter = InterruptBehavior::Interrupter;
        InterruptBehavior::Interrupter = interrupter;

        list_t<Ref<InterruptBehavior> >::iterator itr;
        for(itr = _linkList.begin();itr != _linkList.end(); ++itr)
        {
            (*itr)->Interrupter = interrupter;
        }
        return lastInterrupter;
    }
};
//--------------------------------------------------------- 
/// 统一设置多个IBaseDevAdapterBehavior
template<class IDeviceType>
class DevAdapterSetter : 
    public selecter<Ref<IBaseDevAdapterBehavior<IDeviceType> > >, 
    public IBaseDevAdapterBehavior<IDeviceType>,
    public RefObject
{
public:
    /// 选择类型定义
    typedef selecter<Ref<IBaseDevAdapterBehavior<IDeviceType> > > SelecterType;
    /// 适配设备
    virtual void SelectDevice(const Ref<IDeviceType>& dev)
    {
        typename list_t<Ref<IBaseDevAdapterBehavior<IDeviceType> > >::iterator itr;
        for(itr = SelecterType::_linkList.begin();itr != SelecterType::_linkList.end(); ++itr)
        {
            (*itr)->SelectDevice(dev);
        }
    }
    /// 释放设备 
    virtual void ReleaseDevice()
    {
        typename list_t<Ref<IBaseDevAdapterBehavior<IDeviceType> > >::iterator itr;
        for(itr = SelecterType::_linkList.begin();itr != SelecterType::_linkList.end(); ++itr)
        {
            (*itr)->ReleaseDevice();
        }
    }
    /// 适配的设备是否有效  
    virtual bool IsValid() const
    {
        return SelecterType::_linkList.size() > 0;
    }
};
//--------------------------------------------------------- 
#ifdef OPEN_LOGGER
/// 统一设置多个ILoggerBehavior
class LoggerSetter : 
    public selecter<Ref<ILoggerBehavior> >, 
    public LoggerBehavior,
    public RefObject
{
public:
    /// 选择类型定义
    typedef selecter<Ref<ILoggerBehavior> > SelecterType;
    /// 适配日志
    virtual void SelectLogger(const LoggerAdapter& logger)
    {
        list_t<Ref<ILoggerBehavior> >::iterator itr;
        for(itr = SelecterType::_linkList.begin();itr != SelecterType::_linkList.end(); ++itr)
        {
            (*itr)->SelectLogger(logger);
        }
        LoggerBehavior::SelectLogger(logger);
    }
    /// 释放日志  
    virtual void ReleaseLogger(const LoggerAdapter* plog = NULL)
    {
        list_t<Ref<ILoggerBehavior> >::iterator itr;
        for(itr = SelecterType::_linkList.begin();itr != SelecterType::_linkList.end(); ++itr)
        {
            (*itr)->ReleaseLogger(plog);
        }
        LoggerBehavior::ReleaseLogger(plog);
    }
};
#else
/// 统一设置多个ILoggerBehavior(空类)
class LoggerSetter : public selecter<Ref<RefObject> >
{
public:
    /// 选择类型定义
    typedef selecter<Ref<RefObject> > SelecterType;
};
#endif
//--------------------------------------------------------- 
/// 命令驱动行为
class CommonCmdDriver : public CommandCollection, public DeviceBehavior
{
protected:
    //----------------------------------------------------- 
    /* 错误信息 */
    Ref<ILastErrBehavior> _activeLastErr;
    LastErrInvoker _objErr;
    LastErrGetter _errGetter;
    //----------------------------------------------------- 
    /* 日志 */
    LoggerSetter _logSetter;
    //----------------------------------------------------- 
    /// 注册内部命令
    void _RegisteInlineCMD()
    {
        _RegisteCMD(CommonCmdDriver, EnumCommand);
        _RegisteCMD(CommonCmdDriver, SetLastError);
        _RegisteCMD(CommonCmdDriver, PrintCommand);
        _RegisteVersionCMD(CommonCmdDriver);
        _RegisteLoggerCMD(CommonCmdDriver);
        _RegisteLastErrCMD(CommonCmdDriver);
        _RegisteInterfaceCMD(CommonCmdDriver, ILastErrBehavior);
    }
    //----------------------------------------------------- 
public:
    //----------------------------------------------------- 
    CommonCmdDriver()
    {
        _objErr.Invoke(_lasterr, _errinfo);
        _errGetter.Add(_objErr).New();
        _activeLastErr = _errGetter;

        _RegisteInlineCMD();
    }
    virtual ~CommonCmdDriver()
    {
        CommandCollection::Clear();
    }
    LC_CMD_ENUMCOMMAND();
    /// 设置错误码和错误信息
    LC_CMD_METHOD(SetLastError)
    {
        string sCode;
        if(!arg.Get("CODE", sCode))
            return false;

        ResetErr();
        _lasterr = ArgConvert::FromString<int>(sCode);
        _errinfo = arg["MSG"].To<string>();
        return true;
    }
    LC_CMD_INTERFACE_GETTER(ILastErrBehavior, _activeLastErr);
    LC_CMD_LOGGER_INVOKE(_logSetter);
    LC_CMD_LASTERR_INVOKE(_errGetter);
    LC_CMD_VERSION();
    LC_CMD_METHOD(PrintCommand)
    {
        LOGGER(FileLogger filelog;
        LoggerAdapter flog;
        string path;
        list_t<string> cmds;
        arg.Get("CMD", cmds);

        if(arg.Get("Path", path))
        {
            if(!filelog.Open(path.c_str()))
                return false;
            flog.Select(filelog);
        }
        else
        {
            flog.Select(_log);
        }
        if(cmds.size() < 1)
        {
            Print(flog);
        }
        else
        {
            list_t<string>::iterator itr;
            Ref<ComplexCommand> complexCmd;
            for(itr = cmds.begin();itr != cmds.end(); ++itr)
            {
                complexCmd = LookUp(itr->c_str());
                if(!complexCmd.IsNull())
                {
                    complexCmd->Print(flog);
                }
                else
                {
                    flog << (*itr) << " is Null" << endl;
                }
            }
        });
        return true;
    }
    //----------------------------------------------------- 
};
//--------------------------------------------------------- 
} // nemespace driver
} // namespace application
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_COMMONCMDDRIVER_H_
//========================================================= 